﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SCSEngine.Sprite.Implements;
using SCSEngine.ResourceManagement;
using SCSEngine.Sprite;
using SCSEngine.Services;
using SCSEngine.Utils.GameObject;
using SVLvsXNA;

namespace TriUan.TriUanGame.Effect
{
    public class Effect : TUDrawableGameComponent, ICompleteable
    {
        protected SCSServices services;
        protected IResourceManager resourceManager;

        public Effect(GamePage gamePage, Vector2 position, int size, List<string> names, bool isTrans, int timeToLive, Color color)
            : base(gamePage)
        {
            resourceManager = (IResourceManager)gamePage.Services.GetService(typeof(IResourceManager));

            this.spriteEngine = new List<Sprite>();
            foreach (string name in names)
            {
                spriteEngine.Add((Sprite)resourceManager.GetResource<ISprite>(name));
            }
            this.originalPos.X = position.X + spriteEngine[0].SpriteData.Data.Texture.Width / 4;
            this.originalPos.Y = position.Y + spriteEngine[0].SpriteData.Data.Texture.Height / 4;
            this.size = size;
            this.isTrans = isTrans;
            this.timeToLive = timeToLive;
            this.color = color;
            this.Initialize();
        }

        public Effect(GamePage gamePage, Vector2 position, int size, List<Sprite> sprites, bool isTrans, int timeToLive, Color color)
            : base(gamePage)
        {
            this.spriteEngine = new List<Sprite>(sprites);
            this.originalPos.X = position.X + spriteEngine[0].SpriteData.Data.Texture.Width / 4;
            this.originalPos.Y = position.Y + spriteEngine[0].SpriteData.Data.Texture.Height / 4;
            this.size = size;
            this.isTrans = isTrans;
            this.timeToLive = timeToLive;
            this.color = color;
            this.Initialize();
        }

        public override void Initialize()
        {
            services = (SCSServices)GamePage.Services.GetService(typeof(SCSServices));

            this.particleEngine = new List<Particle>();
            this.isDead = false;
            this.AddNewParticle();
        }

        public override void Update(GameTime gameTime)
        {
            foreach (Particle particle in particleEngine)
            {
                particle.UpdateParticle(gameTime);
                particle.TimeToLive--;
                if (isTrans)
                {
                    if (particle.ColorOverA <= 15)
                        particle.ColorOverA = 0;
                    else
                        particle.ColorOverA -= 10;
                }
            }
        }

        public override void Draw(GameTime gameTime)
        {
            foreach (Particle particle in particleEngine)
            {
                particle.DrawParticle(gameTime);
            }
        }

        public void Clear()
        {
            particleEngine.Clear();
            spriteEngine.Clear();
        }

        public virtual void AddNewParticle()
        {
        }

        #region Fields
        protected List<Particle> particleEngine;
        protected List<Sprite> spriteEngine;
        // The original of particleEngine
        protected Vector2 originalPos;
        // Report true if all particle is dead
        protected bool isDead;
        // The number of particle
        protected int size;
        // Allow the particle transparent gradually
        protected bool isTrans;
        // Time to live of effect
        protected int timeToLive;
        // Color
        protected Color color;
        #endregion

        #region Properties
        protected List<Sprite> SpriteEngine
        {
            get { return this.spriteEngine; }
            set { this.spriteEngine = value; }
        }
        public Vector2 OriginalPos
        {
            get { return this.originalPos; }
            set { this.originalPos = value; }
        }
        public float OriginalPosX
        {
            get { return this.originalPos.X; }
            set { this.originalPos.X = value; }
        }
        public float OriginalPosY
        {
            get { return this.originalPos.Y; }
            set { this.originalPos.Y = value; }
        }

        public bool IsDead
        {
            get { return this.isDead; }
        }

        public bool IsCompleted
        {
            get
            {
                foreach (Particle particle in particleEngine)
                {
                    if (particle.TimeToLive > 0)
                    {
                        isDead = false;
                        return false;
                    }
                }

                isDead = true;
                return true;
            }
        }
        #endregion

        public event OnCompletedHandler OnCompleted;
    }
}
